/**
 * @file lyric_log.cpp
 * @brief 歌词插件日志输出实现
 * @details 实现统一的日志输出接口，支持插件模式和独立运行模式
 */

#include "lyric_log.h"
#include "utils.h"
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <ctime>
#include <glib.h>

#ifdef _WIN32
#include <windows.h>
#endif

// 全局变量
static lyric_log_func_t g_log_func = NULL;
static int g_is_output_file = 0;
static int g_log_initialized = 0;
static lyric_log_level_t g_log_level = LYRIC_LOG_LEVEL_DEBUG;
static std::ofstream g_log_file;

/**
 * @brief 安全地转换字符串为UTF-8（用于日志输出）
 * @param str 输入字符串（可能不是UTF-8）
 * @return UTF-8字符串（需要调用者释放），如果输入为NULL则返回NULL
 */
static gchar* safe_convert_to_utf8_for_log(const gchar* str) {
    if (!str) {
        return NULL;
    }
    
    // 如果已经是有效的UTF-8，直接返回副本
    if (g_utf8_validate(str, -1, NULL)) {
        return g_strdup(str);
    }
    
    // 尝试转换为UTF-8
    return convert_to_utf8(str);
}

void default_log_output(const char* logstr) {
    if (!logstr) {
        std::cout << "(null)" << std::endl;
        return;
    }
    
    // 注意：当从 internal_log_output 调用时，logstr 已经是UTF-8编码
    // 但为了安全（可能在其他地方直接调用），仍然检查并转换
    if (g_utf8_validate(logstr, -1, NULL)) {
        // 已经是UTF-8，直接输出
        std::cout << logstr << std::endl;
    } else {
        // 不是UTF-8，尝试转换
        gchar* utf8_str = safe_convert_to_utf8_for_log(logstr);
        if (utf8_str) {
            std::cout << utf8_str << std::endl;
            g_free(utf8_str);
        } else {
            // 转换失败，尝试直接输出（可能会乱码，但至少不会崩溃）
            std::cout << logstr << std::endl;
        }
    }
}

// 默认日志输出函数（现在作为公共函数）
static void internal_log_output(lyric_log_level_t level, const char* format, va_list args) {
    const char* level_str = "";
    const char* color_code = "";

    // 如果日志级别小于g_log_level，则不输出
    if (level < g_log_level) {
        return;
    }
    
    // 根据日志级别设置前缀和颜色
    switch (level) {
        case LYRIC_LOG_LEVEL_DEBUG:
            level_str = "[DEBUG]";
            color_code = "\033[36m"; // 青色
            break;
        case LYRIC_LOG_LEVEL_INFO:
            level_str = "[INFO]";
            color_code = "\033[32m"; // 绿色
            break;
        case LYRIC_LOG_LEVEL_WARNING:
            level_str = "[WARNING]";
            color_code = "\033[33m"; // 黄色
            break;
        case LYRIC_LOG_LEVEL_ERROR:
            level_str = "[ERROR]";
            color_code = "\033[31m"; // 红色
            break;
    }
    
    // 在Windows下不使用颜色代码
#ifdef _WIN32
    color_code = "";
    const char* reset_code = "";
#else
    const char* reset_code = "\033[0m"; // 重置颜色
#endif
    
    // 格式化消息
    char buffer[1024]={};
    vsnprintf(buffer, sizeof(buffer), format, args);
    
    // 转换格式化的消息为UTF-8（确保安全输出）
    gchar* utf8_buffer = safe_convert_to_utf8_for_log(buffer);
    const char* output_buffer = utf8_buffer ? utf8_buffer : buffer;
    
    // 输出到标准输出
    printf("%s%s ", color_code, level_str);
    printf("%s", output_buffer);
    printf("%s\n", reset_code);
    fflush(stdout);
    
    // 输出到日志函数（确保传入UTF-8字符串）
    if (g_log_func) {
        g_log_func(output_buffer);
    }
    
    // 同时输出到文件
    if (g_log_file.is_open()) {
        // 获取当前时间
        time_t now = time(0);
        char time_str[100];
        strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(&now));
        g_log_file << "[" << time_str << "] " << level_str << " " << output_buffer << std::endl;
        g_log_file.flush();
    }
    
    // 释放转换后的字符串
    if (utf8_buffer) {
        g_free(utf8_buffer);
    }
}

// deadbeef日志输出函数将在plugin.cpp中定义

void lyric_log_init(lyric_log_func_t log_func, int is_output_file, lyric_log_level_t log_level) {
    g_is_output_file = is_output_file;
    g_log_level = log_level;
    
    // 打开日志文件
    if (g_is_output_file) {
        g_log_file.open("lyricbar_debug.log", std::ios::app);
        if (g_log_file.is_open()) {
            g_log_file << "\n=== LyricBar Log Session Started ===" << std::endl;
        }
    }
    
    if (log_func) {
        g_log_func = log_func;
    } else {
        // 默认使用标准输出
        g_log_func = default_log_output;
    }
    
    g_log_initialized = 1;
    
    // 输出初始化信息
    lyric_log_info("LyricBar log system initialized");
}

void lyric_log_cleanup(void) {
    if (g_log_initialized) {
        lyric_log_info("LyricBar log system cleanup");
        g_log_func = NULL;
        g_is_output_file = 0;
        g_log_initialized = 0;
        
        // 关闭日志文件
        if (g_log_file.is_open()) {
            g_log_file << "=== LyricBar Log Session Ended ===" << std::endl;
            g_log_file.close();
        }
    }
}

void lyric_log_debug(const char* format, ...) {
    if (!g_log_initialized) return;
    
    va_list args;
    va_start(args, format);
    internal_log_output(LYRIC_LOG_LEVEL_DEBUG, format, args);
    va_end(args);
}

void lyric_log_info(const char* format, ...) {
    if (!g_log_initialized) return;
    
    va_list args;
    va_start(args, format);
    internal_log_output(LYRIC_LOG_LEVEL_INFO, format, args);
    va_end(args);
}

void lyric_log_warning(const char* format, ...) {
    if (!g_log_initialized) return;
    
    va_list args;
    va_start(args, format);
    internal_log_output(LYRIC_LOG_LEVEL_WARNING, format, args);
    va_end(args);
}

void lyric_log_error(const char* format, ...) {
    if (!g_log_initialized) return;
    
    va_list args;
    va_start(args, format);
    internal_log_output(LYRIC_LOG_LEVEL_ERROR, format, args);
    va_end(args);
}

void lyric_log(lyric_log_level_t level, const char* format, ...) {
    if (!g_log_initialized) return;
    
    va_list args;
    va_start(args, format);
    internal_log_output(level, format, args);
    va_end(args);
}
